package ch.trackedbean.data;

import java.util.*;

/**
 *Factory for creating valid/invalid {@link DomA}, {@link DomB}, {@link DomC} or {@link DomD} objects.
 * 
 * @author M. Hautle
 */
public class DomFactory {
    /**
     * Hidden constructor.
     */
    private DomFactory() {
    }

    /**
     * Creates and populates a valid {@link DomA} object.
     * 
     * @return A {@link DomA}
     */
    public static DomA createValidDomA() {
        final DomA d = new DomA();
        fillValidDomA(d);
        return d;
    }

    public static DomA fillValidDomA(final DomA d) {
        fillDomA(d, 4, "abc", "abc", 4);
        return d;
    }

    public static DomA fillDomA(final DomA d, int numberA, String getterA, String textA, int number) {
        d.setNumberA(numberA);
        d.setGetterA(getterA);
        d.setTextA(textA);
        d.setNumber(String.valueOf(number));
        return d;
    }

    /**
     * Creates and populates a invalide {@link DomA} object.
     * 
     * @return A invalide {@link DomA}
     */
    public static DomA createInvalidDomA() {
        final DomA d = new DomA();
        fillInvalidDomA(d);
        return d;
    }

    public static DomA fillInvalidDomA(final DomA d) {
        fillDomA(d, 2, "ab", "ab", -3);
        return d;
    }

    /**
     * Creates and populates a valid {@link DomB} object.
     * 
     * @return A {@link DomB}
     */
    public static DomB createValidDomB() {
        final DomB b = new DomB();
        final List<DomA> list = new ArrayList<DomA>();
        fillValidDomB(b);
        // list part of DOM B
        list.add(fillValidDomA(new DomA()));
        list.add(fillValidDomB(new DomB()));
        list.add(fillValidDomC(new DomC()));
        b.setListB(list);
        return b;
    }

    public static DomB fillValidDomB(final DomB b) {
        fillValidDomA(b);
        b.setExternalB(5);
        b.setSimple("abc");
        return b;
    }

    /**
     * Creates and populates a invalid {@link DomB} object.
     * 
     * @return A {@link DomB}
     */
    public static DomB createInvalidDomB() {
        final DomB b = new DomB();
        final List<DomA> list = new ArrayList<DomA>();
        fillInvalidDomB(b);
        // list part of DOM B
        list.add(fillInvalidDomB(new DomB()));
        list.add(fillInvalidDomB(new DomB()));
        list.add(fillInvalidDomB(new DomB()));
        b.setListB(list);
        return b;
    }

    public static DomB fillInvalidDomB(final DomB b) {
        fillInvalidDomA(b);
        b.setExternalB(3);
        b.setSimple("ac");
        return b;
    }

    /**
     * Creates and populates a {@link DomC} object for a mapper test.
     * 
     * @return A {@link DomC}
     */
    public static DomC createMapperDomC() {
        final DomC c = new DomC();
        final DomA[] list = new DomA[3];
        fillValidDomC(c);
        // list part of DOM C
        list[0] = fillValidDomA(new DomA());
        list[1] = createValidDomB();
        list[2] = createValidDomB();
        c.setList(list);
        return c;
    }

    /**
     * Creates and populates a valid {@link DomC} object.
     * 
     * @return A {@link DomC}
     */
    public static DomC createValidDomC() {
        final DomC c = new DomC();
        final DomA[] list = new DomA[3];
        fillValidDomC(c);
        // list part of DOM C
        list[0] = fillValidDomA(new DomA());
        list[1] = fillValidDomA(new DomA());
        list[2] = fillValidDomA(new DomA());
        c.setList(list);
        return c;
    }

    public static DomC fillValidDomC(final DomC c) {
        fillValidDomA(c);
        c.setSimple("abc");
        c.setIgnore("bla");
        return c;
    }

    /**
     * Creates and populates a invalid {@link DomC} object.
     * 
     * @return A {@link DomC}
     */
    public static DomC createInvalidDomC() {
        final DomC c = new DomC();
        final DomA[] list = new DomA[3];
        fillInvalidDomC(c, "ab");
        // list part of DOM C
        list[0] = fillInvalidDomC(new DomC(), "ab");
        list[1] = fillInvalidDomC(new DomC(), "ot");
        list[2] = fillInvalidDomC(new DomC(), "ab");
        c.setList(list);
        return c;
    }

    public static DomC fillInvalidDomC(final DomC c, String textA) {
        fillInvalidDomA(c);
        c.setTextA(textA);
        c.setSimple("ab");
        c.setIgnore("bla");
        return c;
    }

    /**
     * Creates and populates a valid {@link DomD} object.
     * 
     * @return A {@link DomD}
     */
    public static DomD createValidDomD() {
        final DomD d = new DomD();
        d.setOtherDom(createValidDomB());
        final DomD d2 = new DomD();
        d2.setOtherDom(createValidDomC());
        d.setSubDom(d2);
        return d;
    }

    /**
     * Creates and populates a invalid {@link DomD} object.
     * 
     * @return A {@link DomD}
     */
    public static DomD createInvalidDomD() {
        final DomD d = new DomD();
        d.setOtherDom(createInvalidDomA());
        final DomD d2 = new DomD();
        d2.setOtherDom(createInvalidDomA());
        d.setSubDom(d2);
        return d;
    }
}
